// 散点图
import React from 'react';
import { Scatter } from '@antv/g2plot';
import { defaultData } from './mock';
import { getComponentData } from 'src/services/AnalyseManage';
import { WD_TYPE, DL_TYPE, THEME_COLOR } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { bigNumberTransform, digitFormat, isNumber } from 'src/libs/utils';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';

export default class ScatterChart extends ChartService {
	state = {
		chartEl: null,
		data: defaultData,
		xField: '类型',
		yField: '数量',
		sizeField: 'size',
		colorField: 'category',
		titleField: 'name',
		min_max: {},
		eventToken: [],
		dataUnit: [],
		dependencies: [],	//	图表联动参数
		isRender: false
	};

	initEvent = async () => {
		const { data, xField, yField, sizeField, colorField, titleField, min_max } = await this.getConditionData();
		this.setState(
			{
				data: data,
				xField: xField,
				yField: yField,
				sizeField: sizeField,
				colorField: colorField,
				titleField: titleField,
				min_max: min_max,
			},
			() => {
				const line = new Scatter( this.props.id, this.getConfig() );
				line.render();
				this.setState( {
					chartEl: line,
					isRender: true
				} );

				//	数据联动 组装联动参数
				line.on( 'point:click', ( ev ) => {
					if( !this.props.config.mutual.isChainAvailable ) return;

					const intervalElement = ev.target.get( 'element' );
					const data = intervalElement.getModel().data; // 单条数据

					console.log( data );
					const { data: dataConfigs } = this.props.config;

					const itemInfo = ( v ) => {
						return {
							formatType: v.formatType,
							id: [ v.name ],
							quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
							symbol: 'EQ',
							value: [ data[v.title] ]
						};
					};

					const dependencies = [];

					//	取这四个配置作为条件
					[ 'chartScatterXColumns', 'chartScatterYColumns', 'chartScatterNameColumns', 'chartScatterColorColumns' ].forEach( v => {
						if( dataConfigs[v] && dataConfigs[v].length > 0 ) {
							dataConfigs[v].forEach( item => {
								dependencies.push( itemInfo( item ) );
							} );
						}
					} );

					console.log( dependencies );

					if( dependencies.length === 0 ) return;

					PubSub.publish( CHART_LINK, {
						publisherId: this.props.id,
						listenerIds: this.props.config.mutual.chartsChainIds,
						dimension: dependencies,
						tableCode: this.props.config.data.tableCode
					} );
				} );
			}
		);
	};

	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config } = this.props;
		let changeObj = Object.create( null );

		//	判断数据字段是否变化了
		if ( JSON.stringify( prevProps.config.data ) !== JSON.stringify( config.data ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ) {
			changeObj.needDataChange = true;
		}
		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.data.chartScatterYColumnsUnit ) !== JSON.stringify( config.data.chartScatterYColumnsUnit ) ||
			 JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		return changeObj;
	}

	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies ) ) return true;
		return false;
	}

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }>, snapshot?: any ) {
		let { config } = this.props;
		const prevDataConfig = prevProps.config.data || {},
			currentDataConfig = config.data || {};

		if ( snapshot.needStyleChange ) {
			if ( this.state.chartEl ) {
				this.state.chartEl.update( this.getConfig() );
			}
		}

		//	判断数据字段是否变化了
		if (
			JSON.stringify( prevDataConfig.filterFields ) !== JSON.stringify( currentDataConfig.filterFields ) ||
			JSON.stringify( prevDataConfig.filterConditions ) !== JSON.stringify( currentDataConfig.filterConditions ) ||
			JSON.stringify( prevDataConfig.chartScatterSizeColumns ) !== JSON.stringify( currentDataConfig.chartScatterSizeColumns ) ||
			JSON.stringify( prevDataConfig.chartScatterNameColumns ) !== JSON.stringify( currentDataConfig.chartScatterNameColumns ) ||
			JSON.stringify( prevDataConfig.chartScatterColorColumns ) !== JSON.stringify( currentDataConfig.chartScatterColorColumns ) ||
			JSON.stringify( prevDataConfig.chartScatterYColumns ) !== JSON.stringify( currentDataConfig.chartScatterYColumns ) ||
			JSON.stringify( prevDataConfig.chartScatterXColumns ) !== JSON.stringify( currentDataConfig.chartScatterXColumns ) ||
			JSON.stringify( prevState.dependencies ) !== JSON.stringify( this.state.dependencies )
		) {
			// 更新散点的数据
			const { data, xField, yField, sizeField, colorField, titleField, min_max } = await this.getConditionData();
			this.setState(
				{
					data: data,
					xField: xField,
					yField: yField,
					sizeField: sizeField,
					colorField: colorField,
					titleField: titleField,
					min_max: min_max,
				},
				() => {
					this.state.chartEl.update( this.getConfig() );
					this.state.chartEl.changeData( data );
				}
			);
		}
	}

	getConfig = (): any => {
		let { style = {}, data: dataConfigs = {} } = this.props.config;

		// const getPadding = ( value: number, type: string ) => {
		// 	if ( style.isShowLegend && style.legendPosition === type ) {
		// 		const defaultValue = type === 'left' || type === 'right' ? 100 : 30;
		// 		return value ? value + defaultValue : defaultValue;
		// 	}
		// 	return value ? value : 30;
		// };

		let color: any = null;
		if( this.state.chartEl ) {
			// let themeObjectColor = this.state.chartEl.chart.themeObject.colors20;
			let themeObjectColor = [ ...THEME_COLOR ];
			if( style.dataColorList && style.dataColorList.length ) {
				let selectColors = style.dataColorList.map( ( i ) => i.color );
				color = selectColors.concat( themeObjectColor.slice( selectColors.length ), themeObjectColor.slice( 0, selectColors.length - 1 ) ); 
			} else {
				color = themeObjectColor;
			}
		} else {
			if( style.dataColorList && style.dataColorList.length ) {
				let selectColors = style.dataColorList.map( ( i ) => i.color );
				color = selectColors;
			} else {
				color = [ ...THEME_COLOR ];
			}
		}

		return {
			data: this.state.data,
			xField: this.state.xField,
			yField: this.state.yField,
			meta: {
				[this.state.xField]: {
					alias: style.chartXAxisName || this.state.xField,
				},
				[this.state.yField]: {
					alias: style.chartLYAxisName || this.state.yField,
					formatter: ( data ) => {
						return data;
					}
				},
			},
			shape: 'circle',
			// 设置自定义颜色
			color: color,
			colorField: this.state.colorField ? this.state.colorField : '',

			sizeField: this.state.sizeField ? this.state.sizeField : null,
			size: [ 5, 15 ],
			appendPadding: [
				style.chartTopPadding || 0,
				style.chartRightPadding || 0,
				style.chartBottomPadding || 0,
				style.chartLeftPadding || 0
			],
			padding: 'auto',
			pointStyle: {
				lineWidth: 0
			},

			legend: this.getLegendConfig( style ),
			tooltip: this.getToolTipConfig( style ),
			xAxis: this.getXAxisConfig( style ),
			yAxis: this.getYAxisConfig( style, dataConfigs ),
			label: this.getDataLabelConfig( style ),
			interactions: [ { type: 'marker-active' } ],
		};
	};

	// 获取图例配置
	getLegendConfig = ( style ) => {
		// 度量没有图例
		return style.isShowLegend === true && this.state.colorField === 'category'
			? {
				position: style.legendPosition,
				itemName: {
					style: {
						fill: style.legendFontColor,
						fontSize: parseInt( style.legendFontSize || 15 ),
						fontFamily: style.legendFontFamily,
						fontWeight: style.legendFontBold ? 'bold' : 'normal',
						fontStyle: style.legendFontItalic ? 'italic' : 'normal',
					},
				},
			  }
			: false;
	};

	// 获取Y轴配置
	getYAxisConfig = ( style, dataConfigs ) => {
		return {
			tickCount: 5,
			line: style.isShowLYLine
				? {
					style: {
						stroke: style.chartLineColor,
					},
				  }
				: null,
			tickLine: style.isShowLYLine === false ? null : {},
			title:
				style.isShowLYLine && style.isShowLYLineName
					? {
						style: {
							offset: 5,
							fontFamily: style.LYLineFontFamily || 'SimSun',
							fontSize: parseInt( style.LYLineFontSize || 15 ),
							fontWeight: style.LYLineFontBold ? 'bold' : 'normal',
							fontStyle: style.LYLineFontItalic ? 'italic' : 'normal',
							fill: style.LYLineFontColor || '#333',
						},
					  }
					: null,
			// 网格线样式
			grid: style.isHiddenLYGridLine
				? null
				: {
					line: {
						style: {
							stroke: style.chartGridlineColor,
						},
					},
				  },
			// 设置坐标轴文字部分样式
			label: {
				formatter: ( v ) => {
					console.log( v );
					if( !isNumber( v ) ) return v;
					let value: any = parseFloat( v );
					if ( style.chartLYAxisDataUnit === 'percent' ) {
						value =  `${v * 100}%`;
					} else if ( style.chartLYAxisDataUnit === 'tenthousand' ) {
						value =  `${v / 10000}万`;
					} else if ( style.chartLYAxisDataUnit === 'million' ) {
						value = `${v / 1000000}百万`;
					}  else {
						value = bigNumberTransform( v );
					}

					return `${ value }${dataConfigs.chartScatterYColumnsUnit || ''}`;;
				},

				style: style.chartLineDataColor
					? {
						fill: style.chartLineDataColor,
					  }
					: {},
			},
		};
	};

	// 获取X轴配置
	getXAxisConfig = ( style ) => {
		return {
			tickCount: 5,
			line:
				style.isShowXLine === false
					? null
					: {
						style: {
							stroke: style.chartLineColor,
						},
					  },
			title:
				style.isShowXLine && style.isShowXLineName
					? {
						offset: 30,
						style: {
							fontFamily: style.XLineFontFamily || 'SimSun',
							fontSize: parseInt( style.XLineFontSize || 15 ),
							fontWeight: style.XLineFontBold ? 'bold' : 'normal',
							fontStyle: style.XLineFontItalic ? 'italic' : 'normal',
							fill: style.XLineFontColor || '#333',
						},
					  }
					: null,
			tickLine: style.isShowXLine === false ? null : {},
			label: {
				style: style.chartLineDataColor
					? {
						fill: style.chartLineDataColor,
						fontSize: style.isShowXLine === false ? 0 : 12,
					  }
					: {
						// 设置X轴不显示，设置axis为null不生效，需要设置不显示label, line, tickline
						fontSize: style.isShowXLine === false ? 0 : 12,
					  },
				rotate: style.chartXAxisLabelTilt ? style.chartXAxisLabelTilt : 0,
			},
		};
	};

	// 获取标签配置
	getDataLabelConfig = ( style ) => {
		return style.isShowLabelData
			? {
				style: {
					fontFamily: style.labelFontFamily || 'SimSun',
					fontSize: parseInt( style.labeleFontSize || 15 ),
					fontWeight: style.labeleFontBold ? 'bold' : 'normal',
					fontStyle: style.labelFontItalic ? 'italic' : 'normal',
					fill: style.labelFontColor || '#333',
				},
				formatter: ( data, c, d ) => {
					// 设置显示最大最小数据
					// const value = data[ this.state.titleField ];
					const value = data[this.state.titleField];
					return value;
					// const { category } = data;
					// const value = data[ this.state.yField ];
					// let min = 0, max = 0;
					// if( this.state.colorField !== 'category' ) {
					// 	// 当颜色图例为空或者是为度量时直接取y轴的最大和最小值
					// 	max = this.state.min_max[ this.state.yField ].max;
					// 	min = this.state.min_max[ this.state.yField ].min;
					// } else {
					// 	if( !this.state.min_max[ category ] ) {
					// 		return null;
					// 	}
					// 	max = this.state.min_max[ category ].max;
					// 	min = this.state.min_max[ category ].min;
					// }

					// if ( style.onlyShowLabelMax && value === max ) {
					// 	return max;
					// } else if ( style.onlyShowLabelMin && value === min ) {
					// 	return min;
					// } else if (
					// 	( style.onlyShowLabelMax && value !== max ) ||
					// 		( style.onlyShowLabelMin && value !== min )
					// ) {
					// 	return null;
					// } else {
					// 	return value;
					// }
				},
				content: '',
			  }
			: null;
	};

	// 设置数据单位
	getDataByDataUnit = ( category, value ) => {
		const categorys = ( category && category.split( '-' ) ) || [];
		const currCategory = categorys[ categorys.length -1 ];
		const dataUnit = this.state.dataUnit;

		const unitItem = dataUnit && dataUnit.length === 1 ? dataUnit[0] : dataUnit.find( v => v.alias === currCategory );
		let unit = unitItem && unitItem.dataUnit ? unitItem.dataUnit : '';

		return {
			name: category,
			value: value && unit ? `${value}${unit}` : value
		};
	};

	// 设置提示config
	getToolTipConfig = ( style ) => {
		// const getToolTipLabel =  ( datum ) => {
		// 	return this.getDataByDataUnit( datum.category, datum.value );					
		// };


		// console.log( getToolTipLabel );

		return style.isShowToolTip !== false
			? {
				fields: [
					this.state.xField,
					this.state.yField,
					this.state.sizeField,
					this.state.colorField !== 'category' && this.state.colorField !== 'categoryNone' ? this.state.colorField : ''
				],
				shared: true,
				// 设置toolTip相关样式
				domStyles: {
					'g2-tooltip-list-item': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
					'g2-tooltip-title': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
				},
				// follow: true,
				showTitle: this.state.titleField ? true : false,
				title: this.state.titleField ? this.state.titleField : null,
				showCrosshairs: false,
				showMarkers: false,
				customContent: ( title, data ) => {
					console.log( data );
					const listItemDom = data.map( v => `<li class="g2-tooltip-list-item">
						${v.name}: ${digitFormat( v.value, 3 )}${this.getDataUnit( v.data, v.name )}</li>` ).join( '' );
					return `<div>
										<div class="g2-tooltip-title">${title}</div>
										<ul class="g2-tooltip-list">
											${listItemDom}
										</ul>
									</div>`;
				}
			  }
			: {
				showMarkers: false,
				showContent: false,
				domStyles: null,
				follow: false,
			  };
	};

	//	获取单位
	getDataUnit( obj, key ) {
		const dataUnitKey = `${key}-dataUnit`;
		return obj[dataUnitKey] || '';
	};

	// 获取散点图的数据
	async getConditionData() {
		const { data: dataConfigs } = this.props.config;
		if (
			dataConfigs.chartScatterXColumns &&
			dataConfigs.chartScatterXColumns.length > 0 &&
			dataConfigs.chartScatterYColumns &&
			dataConfigs.chartScatterYColumns.length > 0
		) {
			const itemInfo = ( v, orderType?, desc? ) => {
				return {
					aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', // 度量的聚合类型
					formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
					alias: v.title.trim(),
					dataType: v.dataType,
					frontendId: '',
					id: v.name,
					orderType: v.modelType === DL_TYPE && !v.orderType ? 'ASC' : v.orderType, // 排序方式
					quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
					symbol: '',
					type: v.type,
					value: '',
					dataUnit: v.dataUnit,
					precision: v.precision
				};
			};
			const x = dataConfigs.chartScatterXColumns.map( ( v ) => {
				return itemInfo( v );
			} );

			const y = dataConfigs.chartScatterYColumns.map( ( v ) => {
				return itemInfo( v );
			} );

			const category = dataConfigs.chartScatterColorColumns
				? dataConfigs.chartScatterColorColumns.map( ( v ) => {
					return itemInfo( v );
				  } )
				: [];

			const categoryIsDL = category.length > 0 ? category[0].quota === 'DL' : false;
			const name = dataConfigs.chartScatterNameColumns
				? dataConfigs.chartScatterNameColumns.map( ( v ) => {
					return itemInfo( v );
				  } )[0]
				: null;

			const size = dataConfigs.chartScatterSizeColumns
				? dataConfigs.chartScatterSizeColumns.map( ( v ) => {
					return itemInfo( v );
				  } )[0]
				: null;

			// 内部筛选的 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );

			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						customParams: {
							scatterName: name && name,
							scatterSize: size && size,
						},
						tableName: this.props.config.data.tableCode,
						x: x,
						y: y,
						category: category,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions ),
					},
					needAutoRefresh: true,
					tableType: 'scatter',
				},
				type: 'bar',
				tenantCode: this.props.tenantCode
			};

			let pageResponse = await getComponentData( request );
			if ( pageResponse.data && pageResponse.data.success ) {
				let { rows, extra } = pageResponse.data.data;

				if( category.length === 0 ) {
					rows = rows.map( item => {
						return {
							...item, categoryNone: '分类1'
						};
					} );				
				}
				// const newRows = rows.map( ( v ) => {
				// 	const item = y.find( i => i.alias.trim() === this.state.yField );

				// 	let unit = item && item.dataUnit && item.quota === 'DL' ? DATA_UNIT_TYPES[ item.dataUnit ].label : '', sizeUnit = '';
				// 	if ( size ) {
				// 		sizeUnit = size.dataUnit ? DATA_UNIT_TYPES[ size.dataUnit ].label : '';
				// 		return {
				// 			...v,
				// 			[y[0].alias]: v[y[0].alias] ? `${v[y[0].alias]}${unit || ''}` : v[y[0].alias],
				// 			[size.alias]: v[size.alias] ? `${v[size.alias]}${sizeUnit || ''}` : v[size.alias],
				// 		};
				// 	}
				// 	return {
				// 		...v,
				// 		[y[0].alias]: v[y[0].alias] ? `${v[y[0].alias]}${unit || ''}` : v[y[0].alias],
				// 	};
				// } );

				return {
					data: rows,
					xField: x[0].alias,
					yField: y[0].alias,
					sizeField: size ? size.alias : '',
					colorField: category.length === 0 ? 'categoryNone' : categoryIsDL ? category[0].alias : 'category',
					titleField: name ? 'name' : null,
					min_max: ( extra && extra.maxmin ) || {},
				};
			}
		}

		return {
			data: defaultData,
			xField: '类型',
			yField: '数量',
			sizeField: 'size',
			colorField: 'category',
			titleField: 'name',
			min_max: {},
		};
	}

	render() {
		return <div id={this.props.id} style={{ height: '100%' }}></div>;
	}
}
